package com.mlethe.library.widget.wheelview.picker;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;

import androidx.annotation.IntDef;
import androidx.annotation.IntRange;
import androidx.annotation.Nullable;

import com.mlethe.library.widget.wheelview.R;
import com.mlethe.library.widget.wheelview.WheelView;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * 分、秒 WheelView
 *
 * @author Mlethe
 * @version v1.0.0
 * @since 2018/8/20.
 */
public class TimeWheelView extends WheelView<Integer> {

    @IntDef({MINUTE, SECOND})
    @Retention(RetentionPolicy.SOURCE)
    public @interface TimeType {
    }

    public static final int MINUTE = 0x01;
    public static final int SECOND = 0x02;

    @TimeType
    private int mType = MINUTE;
    private int mMaxTime = -1;
    private int mMinTime = -1;

    public TimeWheelView(Context context) {
        this(context, null);
    }

    public TimeWheelView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TimeWheelView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TimeWheelView);
        mType = typedArray.getInt(R.styleable.TimeWheelView_wvType, mType);
        int selectedDefVal = 0;
        if (mType == MINUTE) {
            selectedDefVal = Calendar.getInstance().get(Calendar.MINUTE);
        } else if (mType == SECOND) {
            selectedDefVal = Calendar.getInstance().get(Calendar.SECOND);
        }
        int selectedTime = typedArray.getInt(R.styleable.TimeWheelView_wvSelectedTime, selectedDefVal);
        typedArray.recycle();
        initData();
        if (selectedTime > 60) {
            selectedTime = selectedTime % 60;
        }
        setSelectedTime(selectedTime);
    }

    /**
     * 初始化数据
     */
    private void initData() {
        List<Integer> list = new ArrayList<>(1);
        for (int i = 0; i <= 59; i++) {
            list.add(i);
        }
        super.setData(list);
    }

    public void setMaxTime(@IntRange(from = 0, to = 59) int maxTime) {
        mMaxTime = maxTime;
        checkCurrentSelected(getSelectedItemData());
    }

    public void setMinTime(@IntRange(from = 0, to = 59) int minTime) {
        mMinTime = minTime;
        checkCurrentSelected(getSelectedItemData());
    }

    /**
     * 获取类型
     * @return
     */
    public int getType() {
        return mType;
    }

    /**
     * 设置控件类型
     * @param type
     */
    public void setType(@TimeType int type) {
        this.mType = type;
        int selectedDefVal = 0;
        if (mType == MINUTE) {
            selectedDefVal = Calendar.getInstance().get(Calendar.MINUTE);
        } else if (mType == SECOND) {
            selectedDefVal = Calendar.getInstance().get(Calendar.SECOND);
        }
        setSelectedTime(selectedDefVal);
    }

    /**
     * 获取选中的分、秒
     *
     * @return 选中的分、秒
     */
    public int getSelectedTime() {
        return getSelectedItemData();
    }

    /**
     * 设置选中的分、秒
     *
     * @param selectedTime 选中的分、秒
     */
    public void setSelectedTime(int selectedTime) {
        setSelectedTime(selectedTime, false);
    }

    /**
     * 设置选中的分、秒
     *
     * @param selectedTime   选中的分、秒
     * @param isSmoothScroll 是否平滑滚动
     */
    public void setSelectedTime(int selectedTime, boolean isSmoothScroll) {
        setSelectedTime(selectedTime, isSmoothScroll, 0);
    }

    /**
     * 设置选中的分、秒
     *
     * @param selectedTime   选中的分、秒
     * @param isSmoothScroll 是否平滑滚动
     * @param smoothDuration 平滑滚动持续时间
     */
    public void setSelectedTime(int selectedTime, boolean isSmoothScroll, int smoothDuration) {
        if (selectedTime >= 0 && selectedTime <= 59) {
            int shouldSelected = selectedTime;
            if (isMoreThanMaxTime(selectedTime)) {
                shouldSelected = mMaxTime;
            } else if (isLessThanMinTime(selectedTime)) {
                shouldSelected = mMinTime;
            }
            updateSelectedTime(shouldSelected, isSmoothScroll, smoothDuration);
        }
    }

    /**
     * 更新选中的分、秒
     *
     * @param selectedTime   选中的分、秒
     * @param isSmoothScroll 是否平滑滚动
     * @param smoothDuration 平滑滚动持续时间
     */
    private void updateSelectedTime(int selectedTime, boolean isSmoothScroll, int smoothDuration) {
        setSelectedItemPosition(selectedTime, isSmoothScroll, smoothDuration);
    }

    @Override
    public void setData(List<Integer> dataList) {
        throw new UnsupportedOperationException("You can not invoke setData method in " + TimeWheelView.class.getSimpleName() + ".");
    }

    @Override
    protected void onItemSelected(Integer data, int position) {
        checkCurrentSelected(data);
    }

    private void checkCurrentSelected(int data) {
        if (isMoreThanMaxTime(data)) {
            setSelectedTime(mMaxTime);
        } else if (isLessThanMinTime(data)) {
            setSelectedTime(mMinTime);
        }
    }

    private boolean isMoreThanMaxTime(int data) {
        return data > mMaxTime && mMaxTime > 0;
    }

    private boolean isLessThanMinTime(int data) {
        return data < mMinTime && mMinTime > 0;
    }
}
